Understanding Kotlin Syntax, Variables, and Constants
Course: Android App Development
Topic: Understanding Kotlin Syntax, Variables, and Constants
Course Link: Android App Development Course
Demo Link: Register for a Course Demo
Official Website: JustAcademy
1. Introduction to Kotlin
Kotlin is a modern, statically typed programming language widely used for Android application development. It is designed to be concise, readable, expressive, and safer against common programming errors. Kotlin works with the Java ecosystem and is supported by Android Studio, making it a practical choice for building Android applications.
Before developing Android applications, it is important to understand Kotlin syntax, variables, constants, data types, operators, and naming conventions. These fundamentals help developers write clear code, manage application data, and reduce mistakes.
For example, an Android application may need to store a user's name, calculate a product price, track a login status, or maintain a fixed application configuration value. Kotlin variables and constants make these tasks straightforward.
2. Learning Objectives
After completing this topic, learners should be able to:
- Understand the basic structure of a Kotlin program.
- Identify Kotlin keywords, identifiers, expressions, and statements.
- Declare variables using
val and var.
- Understand the difference between mutable and read-only variables.
- Work with common Kotlin data types.
- Understand type inference and explicit type declarations.
- Use constants with
const val where appropriate.
- Apply arithmetic, assignment, and string operations.
- Understand nullable and non-nullable types.
- Apply Kotlin syntax in Android application examples.
3. Basic Structure of a Kotlin Program
A Kotlin source file generally uses the .kt extension. A simple Kotlin program can contain a package declaration, imports, variables, functions, classes, and executable statements.
Example: A Simple Kotlin Program
fun main() {
val appName = "My Android App"
println("Welcome to $appName")
}
Explanation:
fun is the keyword used to declare a function.
main() is the entry-point function for a standard Kotlin console program.
val appName declares a read-only variable.
"My Android App" is a string value.
println() displays text followed by a line break.
$appName inserts the variable's value into the string.
In Android applications, code is commonly organized into classes, functions, activities, composable functions, and other application components rather than relying on a console-style main() function.
4. Understanding Kotlin Syntax
Syntax refers to the rules used to write valid statements and expressions in a programming language. Kotlin syntax is designed to reduce unnecessary code while maintaining readability.
4.1 Statements and Expressions
A statement performs an action, while an expression produces a value. For example, assigning a value to a variable is an assignment statement, while 10 + 20 is an expression that evaluates to 30.
fun main() {
val firstNumber = 10
val secondNumber = 20
val total = firstNumber + secondNumber
println(total)
}
Output:
30
4.2 Semicolons
Kotlin normally does not require semicolons at the end of statements. Each statement can be written on a separate line.
val courseName = "Android Development"
val duration = 60
println(courseName)
println(duration)
Although semicolons can be used in certain situations, omitting them is the usual Kotlin style.
4.3 Comments
Comments explain code and are ignored during normal program execution.
Single-line comment:
// Store the user's age
val age = 25
Multi-line comment:
/*
This section stores
application information.
*/
val applicationName = "Learning App"
Documentation comment:
/**
* Returns the total price of an item.
*/
fun calculateTotal(price: Double, quantity: Int): Double {
return price * quantity
}
Use comments to explain important decisions or non-obvious logic instead of repeating what the code already makes clear.
4.4 Identifiers and Naming Rules
An identifier is the name assigned to a variable, function, class, or other program element.
Examples of identifiers include userName, totalPrice, calculateDiscount, and Student.
- Names are case-sensitive:
userName and username are different identifiers.
- Names generally begin with a letter or underscore.
- Names can contain letters, digits, and underscores after the first character.
- Spaces are not allowed in ordinary identifiers.
- Reserved keywords should not be used as ordinary identifiers.
- Choose descriptive names that explain the purpose of the value.
4.5 Kotlin Naming Conventions
| Element |
Convention |
Example |
| Variable |
camelCase |
userName |
| Function |
camelCase |
calculateTotal() |
| Class |
PascalCase |
StudentProfile |
| Constant |
UPPER_SNAKE_CASE commonly used for top-level constants |
MAX_LOGIN_ATTEMPTS |
| Package |
Usually lowercase |
com.example.learningapp |
5. What Are Variables?
A variable is a named storage location used to represent a value in a program. Kotlin uses the keywords val and var to declare variables.
Variables are useful when an application needs to store information such as a user's name, shopping cart quantity, selected theme, current score, or login status.
5.1 Declaring a Variable
val studentName = "Aarav"
var studentAge = 21
println(studentName)
println(studentAge)
Here, studentName is declared using val, while studentAge is declared using var.
5.2 Variable Declaration with an Explicit Type
You can specify a variable's data type after its name using a colon.
val studentName: String = "Aarav"
var studentAge: Int = 21
val courseFee: Double = 14999.50
val isEnrolled: Boolean = true
Explicit types make the intended data type clear. Kotlin can also infer the type when a value is supplied during declaration.
6. Understanding the var Keyword
The var keyword declares a mutable variable. A mutable variable can be assigned a new value after initialization, provided the new value is compatible with its declared type.
Example
fun main() {
var score = 50
println(score)
score = 75
println(score)
score = score + 10
println(score)
}
Output:
50
75
85
Explanation: The variable score starts at 50, changes to 75, and then increases to 85.
When Should You Use var?
- When a value needs to be updated repeatedly.
- When maintaining a changing counter or score.
- When tracking a changing selection or state in a suitable context.
- When the program needs to assign different values to the same variable over time.
7. Understanding the val Keyword
The val keyword declares a read-only variable that can be assigned only once. After initialization, you cannot reassign that variable to a different value.
Example
fun main() {
val appName = "Learning App"
println(appName)
// This would cause a compilation error:
// appName = "Shopping App"
}
Explanation: The value of appName cannot be reassigned after initialization.
When Should You Use val?
- When a value should not be reassigned.
- When storing a name or label that remains fixed within the relevant scope.
- When receiving function parameters or calculating a result that does not need reassignment.
- When you want to make code easier to reason about and maintain.
Prefer val by default. Change to var only when reassignment is genuinely required.
8. Difference Between val and var
| Feature |
val |
var |
| Meaning |
Read-only variable |
Mutable variable |
| Reassignment |
Not allowed after initialization |
Allowed when type-compatible |
| Typical use |
Values that should not be reassigned |
Values that need to change |
| Example |
val name = "Riya" |
var age = 20 |
| Compiler enforcement |
Rejects reassignment |
Allows reassignment |
Important: A val reference does not necessarily make the object it points to immutable. For example, a read-only list reference cannot be reassigned, but the underlying object may have mutable behavior if its type supports it.
val names = mutableListOf("Asha", "Ravi")
names.add("Neha") // Allowed: the list is mutable
// names = mutableListOf("Sam") // Not allowed: val cannot be reassigned
9. Understanding Constants in Kotlin
A constant represents a value intended to remain fixed. Kotlin supports compile-time constants through the const val declaration in supported locations.
9.1 Using const val
const val MAX_LOGIN_ATTEMPTS = 3
const val APP_NAME = "Learning App"
fun main() {
println(APP_NAME)
println(MAX_LOGIN_ATTEMPTS)
}
Output:
Learning App
3
const val is suitable for compile-time constant values, such as string and primitive values that meet Kotlin's restrictions. It must be declared at the top level or inside an appropriate object or companion object. It cannot be declared as a local variable inside an ordinary function.
9.2 Difference Between val and const val
| Feature |
val |
const val |
| Purpose |
Read-only property or variable |
Compile-time constant |
| Allowed value expressions |
Can use expressions evaluated at runtime where appropriate |
Must use a compile-time constant expression |
| Declaration locations |
Local variables, properties, and other supported contexts |
Top-level and supported object or companion-object declarations |
| Example |
val currentTime = System.currentTimeMillis() |
const val MAX_ITEMS = 100 |
9.3 Example of a Regular val That Is Not a Compile-Time Constant
val installationTime = System.currentTimeMillis()
const val MAX_ITEMS = 100
The installation time depends on runtime execution, so it cannot be declared as a const val. The integer value assigned to MAX_ITEMS is known at compile time.
9.4 Constants Inside an Object
object AppConfig {
const val API_VERSION = "v1"
const val MAX_RETRIES = 3
}
fun main() {
println(AppConfig.API_VERSION)
println(AppConfig.MAX_RETRIES)
}
This approach can help organize application-wide configuration values. Keep sensitive credentials and private API secrets out of source code; a constant does not make a secret secure.
10. Kotlin Data Types
A data type defines the kind of value a variable can hold. Kotlin is statically typed, which means types are checked by the compiler, although type inference often lets you omit explicit type declarations.
| Data Type |
Purpose |
Example |
Int |
Whole numbers |
val age: Int = 25 |
Long |
Large whole numbers |
val population: Long = 8000000L |
Float |
Single-precision decimal numbers |
val rating: Float = 4.5f |
Double |
Double-precision decimal numbers |
val price: Double = 299.99 |
Boolean |
Logical true or false values |
val isActive: Boolean = true |
Char |
A single character |
val grade: Char = 'A' |
String |
A sequence of characters |
val city: String = "Mumbai" |
10.1 Integer Types
Kotlin provides Byte, Short, Int, and Long for whole-number values with different ranges.
val smallNumber: Byte = 100
val shortNumber: Short = 20000
val studentCount: Int = 1500
val largeNumber: Long = 9000000000L
The L suffix identifies a long integer literal when needed.
10.2 Floating-Point Types
Use Float and Double for fractional numbers. A Double literal is the default for decimal values unless a different type is specified.
val temperature: Float = 28.5f
val productPrice: Double = 799.99
For financial calculations requiring exact decimal behavior, consider an appropriate decimal representation such as Java's BigDecimal, because binary floating-point values can introduce rounding differences.
10.3 Boolean Type
A Boolean variable stores either true or false.
val isLoggedIn = true
val hasPermission = false
println(isLoggedIn)
println(hasPermission)
Booleans are useful for login checks, form validation, feature flags, and application conditions.
10.4 Char and String Types
val firstLetter: Char = 'K'
val courseName: String = "Android App Development"
println(firstLetter)
println(courseName)
Character literals use single quotes, while string literals use double quotes.
11. Type Inference
Type inference allows Kotlin to determine a variable's type from its initial value. It reduces repetitive declarations while preserving static type checking.
val userName = "Amit" // String
val userAge = 22 // Int
val courseFee = 15000.0 // Double
val isActive = true // Boolean
In these examples, Kotlin determines each type automatically.
11.1 Explicit Type Declaration
val userName: String = "Amit"
val userAge: Int = 22
Explicit declarations can improve readability when the intended type is not obvious or when a declaration is separated from its initialization.
11.2 Declaring a Variable Before Initialization
fun main() {
val score: Int
score = 95
println(score)
}
A local variable can be declared without an initial value when its type is specified, provided Kotlin can verify that it is initialized before it is read. A val must be assigned exactly once along the relevant execution path.
12. Variable Scope
Scope determines where a variable can be accessed. Kotlin variables may be local to a function or block, or declared as properties at class or file level.
12.1 Local Variables
fun displayMessage() {
val message = "Welcome to Kotlin"
println(message)
}
The variable message is local to the function and cannot be accessed directly from unrelated functions.
12.2 Top-Level Properties
val applicationName = "Study App"
fun showApplicationName() {
println(applicationName)
}
A top-level property is declared outside a class or function and can be accessed according to its visibility and package rules.
12.3 Block Scope
fun main() {
if (true) {
val message = "Inside the block"
println(message)
}
// message is not accessible here
}
Keeping variables within the smallest practical scope reduces accidental dependencies and makes code easier to understand.
13. Nullable and Non-Nullable Variables
Kotlin's type system helps prevent null-related errors by treating types as non-nullable by default. To allow a variable to hold null, add a question mark to its type.
13.1 Non-Nullable Variable
val userName: String = "Neha"
// userName = null // Compilation error
13.2 Nullable Variable
var middleName: String? = null
middleName = "Kumar"
println(middleName)
The type String? permits either a string or null.
13.3 Safe Calls and Null Checks
val name: String? = null
println(name?.length)
The safe-call operator ?. accesses a property only when the receiver is not null. In this example, the result is null.
You can also provide a fallback value using the Elvis operator ?:.
val displayName: String? = null
val result = displayName ?: "Guest"
println(result)
Output:
Guest
Use nullable types deliberately when data may be absent, such as an optional profile field or a value that has not yet been loaded from a service.
14. Assigning and Updating Values
The assignment operator = assigns a value to a mutable variable or initializes a variable. Compound assignment operators combine an operation with reassignment.
fun main() {
var quantity = 5
quantity += 2
println(quantity)
quantity -= 1
println(quantity)
quantity *= 3
println(quantity)
}
Output:
7
6
18
Compound assignments should be used only with variables that permit reassignment, such as those declared with var.
15. Arithmetic Operators
Kotlin supports common arithmetic operators for numerical calculations.
| Operator |
Purpose |
Example |
Result |
+ |
Addition |
10 + 5 |
15 |
- |
Subtraction |
10 - 5 |
5 |
* |
Multiplication |
10 * 5 |
50 |
/ |
Division |
10 / 5 |
2 |
% |
Remainder |
10 % 3 |
1 |
Example: Calculating a Total Price
fun main() {
val itemPrice = 250.0
val quantity = 4
val totalPrice = itemPrice * quantity
println("Total price: $totalPrice")
}
Output:
Total price: 1000.0
16. Working with Strings and String Templates
Kotlin string templates allow you to insert variable values and expressions directly into strings.
16.1 Using the Dollar Sign
val userName = "Priya"
println("Welcome, $userName")
16.2 Using Curly Braces for Expressions
val price = 500
val quantity = 3
println("Total: ${price * quantity}")
Output:
Total: 1500
String templates are particularly useful for displaying information, creating messages, and preparing user-facing text. In Android UI code, use resource strings for user-visible text when appropriate to support localization.
17. Variables in Android Development
Kotlin variables are used throughout Android applications to represent user input, application state, configuration, API responses, and calculated values.
17.1 Example: User Profile Data
data class UserProfile(
val name: String,
val age: Int,
val email: String
)
fun main() {
val user = UserProfile(
name = "Ananya",
age = 24,
email = "[email protected]"
)
println(user.name)
println(user.age)
println(user.email)
}
This example uses read-only properties in a data class to represent a simple user profile. Real applications should validate input and handle personal information carefully.
17.2 Example: Managing a Shopping Cart Quantity
fun main() {
var cartQuantity = 1
cartQuantity += 1
cartQuantity += 1
println("Items in cart: $cartQuantity")
}
Output:
Items in cart: 3
The quantity is mutable because the user may add or remove items.
17.3 Example: Application Configuration
object AppConstants {
const val DEFAULT_PAGE_SIZE = 20
const val SUPPORT_EMAIL = "[email protected]"
}
fun main() {
println(AppConstants.DEFAULT_PAGE_SIZE)
println(AppConstants.SUPPORT_EMAIL)
}
This pattern can group stable configuration values in one place. Never store passwords, private tokens, or production secrets in source-code constants.
18. Common Kotlin Errors and Their Solutions
| Error |
Why It Happens |
Solution |
| Reassigning a val |
A read-only variable is assigned a new value. |
Use var only if reassignment is required. |
| Type mismatch |
The assigned value does not match the declared type. |
Use a compatible value or an appropriate conversion. |
| Uninitialized variable |
A variable is read before a value is assigned. |
Initialize it before use and check all execution paths. |
| Nullability error |
A nullable value is used where a non-null value is required. |
Use a null check, safe call, or Elvis operator. |
| Invalid identifier |
A name violates Kotlin naming rules or conflicts with a keyword. |
Use a valid, descriptive identifier. |
| Invalid const declaration |
A runtime expression or unsupported location is used for const val. |
Use a compile-time constant expression in a supported location. |
| Incorrect string quotes |
Single and double quotes are used incorrectly. |
Use single quotes for Char and double quotes for String. |
19. Best Practices for Kotlin Variables and Constants
- Prefer
val over var whenever reassignment is unnecessary.
- Use descriptive names such as
totalPrice instead of vague names such as x.
- Follow camelCase for variables and functions, and PascalCase for classes.
- Use
const val for eligible compile-time constants.
- Keep variables in the smallest practical scope.
- Use explicit types when they improve clarity.
- Handle nullable values safely rather than relying on unsafe assumptions.
- Avoid unnecessary mutable state because it can make bugs harder to trace.
- Separate application configuration from business logic where appropriate.
- Do not put confidential credentials or private tokens into source code.
- Use Android string resources for text that must support translation.
- Run the compiler and tests regularly to catch type and initialization errors early.
20. Practical Exercise: Student Information Program
Objective: Create a Kotlin program that stores student information, calculates a result, and displays the output using variables and constants.
Requirements
- Declare a constant for the maximum number of subjects.
- Store the student's name using
val.
- Store marks for three subjects using numeric variables.
- Calculate the total and average marks.
- Display the student's name, total, and average using string templates.
Sample Solution
const val SUBJECT_COUNT = 3
fun main() {
val studentName = "Rahul"
val subjectOne = 80
val subjectTwo = 75
val subjectThree = 90
val totalMarks = subjectOne + subjectTwo + subjectThree
val averageMarks = totalMarks.toDouble() / SUBJECT_COUNT
println("Student: $studentName")
println("Total Marks: $totalMarks")
println("Average Marks: $averageMarks")
}
Expected output:
Student: Rahul
Total Marks: 245
Average Marks: 81.66666666666667
The average is calculated using a Double so that division preserves the fractional part. In a real application, you could format the result to a fixed number of decimal places.
21. Additional Practice Questions
- Declare a read-only variable to store your name.
- Declare a mutable variable to store your current score and update it.
- Create a
const val for the maximum number of login attempts.
- Declare variables using
Int, Double, Boolean, Char, and String.
- Write a program that calculates the total cost of three products.
- Create a nullable string and display a fallback value when it is null.
- Write a program that uses string templates to display a student's details.
- Identify and fix a compilation error caused by reassigning a
val.
22. Interview Questions and Answers
Q1. What is Kotlin?
Kotlin is a statically typed programming language commonly used for Android development. It offers concise syntax, null-safety features, and interoperability with Java.
Q2. What is a variable?
A variable is a named value used to store or represent data in a program.
Q3. What is the difference between val and var?
val prevents reassignment after initialization, whereas var allows reassignment to a compatible value.
Q4. What is const val?
const val declares a compile-time constant in a supported location using an eligible constant expression.
Q5. What is type inference?
Type inference is Kotlin's ability to determine a variable's type from its initializer without requiring the developer to write the type explicitly.
Q6. Is Kotlin case-sensitive?
Yes. For example, userName and username are different identifiers.
Q7. Does Kotlin require semicolons?
No. Semicolons are usually unnecessary because Kotlin can identify statement boundaries from the source code structure.
Q8. What is a nullable type?
A nullable type is a type that permits a value to be null. It is marked with a question mark, such as String?.
Q9. What is the difference between String and Char?
String represents a sequence of characters, while Char represents one character. Strings use double quotes and character literals use single quotes.
Q10. Can a val object be modified?
It depends on the object. A val prevents reassignment of the reference, but it does not automatically make the referenced object immutable.
Q11. Can const val be declared inside a function?
No. A compile-time constant must be declared at the top level or in a supported object or companion-object location, not as a local variable inside a function.
Q12. Why is val generally preferred?
Using val where possible reduces unintended reassignment and makes program behavior easier to understand and maintain.
23. Quick Revision Checklist
- Kotlin source files commonly use the
.kt extension.
fun declares a function.
val declares a read-only variable.
var declares a mutable variable.
const val declares an eligible compile-time constant.
- Kotlin can infer types from initial values.
- Common types include
Int, Long, Float, Double, Boolean, Char, and String.
- Nullable types use a question mark, such as
String?.
- String templates use
$name or ${expression}.
- Kotlin generally does not require semicolons.
- Use clear names and prefer immutable references when possible.
- Practice by creating small programs before applying the concepts to complete Android applications.
24. Useful Learning Resources
25. Conclusion
Understanding Kotlin syntax, variables, and constants is an essential first step toward Android application development. The val and var keywords help manage read-only and mutable values, while const val supports eligible compile-time constants. Data types, type inference, scope, null-safety, operators, and string templates provide the foundation for writing reliable and readable Kotlin programs.
Practice these concepts with small programs, review compiler errors, and gradually apply them to Android features such as user profiles, forms, shopping carts, and application settings. A strong understanding of these fundamentals will make more advanced Kotlin and Android topics easier to learn.